package com.fengycx.remote.impl;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.lang.Assert;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.fengycx.constants.GlobalExceptionCode;
import com.fengycx.feign.CreateOrderApi;
import com.fengycx.param.CalculateResultParam;
import com.fengycx.param.SharedAmountDto;
import com.fengycx.param.SharedAmountResult;
import com.fengycx.pojo.domain.*;
import com.fengycx.result.CallDriverCalculatedBillResult;
import com.fengycx.result.R;
import com.fengycx.service.*;
import com.fengycx.utils.AssertUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RestController;

import java.math.BigDecimal;

/**
 * 创建司机订单明细 Feign接口
 */
@RestController
public class CallDriverCalculateImpl implements CreateOrderApi {


    @Autowired
    private IChargeRuleReturnService chargeRuleReturnService;
    @Autowired
    private IChargeRuleWaitService chargeRuleWaitService;
    @Autowired
    private IChargeRuleStartService chargeRuleStartService;
    @Autowired
    private IProfitsharingRuleBaseService profitsharingRuleBaseService;
    @Autowired
    private IProfitsharingRuleDeductService profitsharingRuleDeductService;
    @Override
    public R<CallDriverCalculatedBillResult> getCallDriverCalculatedBillResult(CalculateResultParam param) {
        //判断三个规则是否存在
        //业务实现
        ChargeRuleReturn ruleReturn = chargeRuleReturnService.getOne(new LambdaQueryWrapper<ChargeRuleReturn>().eq(ChargeRuleReturn::getEnable, 0));
        AssertUtil.isNotNull(ruleReturn,"返程规则未开启！");

        ChargeRuleWait ruleWait = chargeRuleWaitService.getOne(new LambdaQueryWrapper<ChargeRuleWait>().eq(ChargeRuleWait::getEnable, 0));
        AssertUtil.isNotNull(ruleWait,"等待规则未开启！");

        //订单创建时间
        int hour = DateUtil.hour(param.getCurrentTime(), true);
        //得到订单创建的时间段
        ChargeRuleStart ruleStart = chargeRuleStartService.getOne(new LambdaQueryWrapper<ChargeRuleStart>()
                .le(ChargeRuleStart::getHourStart, hour)
                .ge(ChargeRuleStart::getHourEnd, hour));
        AssertUtil.isNotNull(ruleStart,"时间段匹配规则不存在！");

        //3.业务实现
        CallDriverCalculatedBillResult callDriverCalculatedBillResult = new CallDriverCalculatedBillResult();

        //起步价基础里程
        BigDecimal baseMileage = ruleStart.getBaseMileage();
        callDriverCalculatedBillResult.setBaseMileage(baseMileage);
        //起步价格
        callDriverCalculatedBillResult.setBaseMileageAmount(ruleStart.getAmount());
        //超出起步里程每公里的单价
        BigDecimal exceedEveryKmAmount = ruleStart.getExceedEveryKmAmount();
        callDriverCalculatedBillResult.setExceedBaseMileageAmount(exceedEveryKmAmount);
        BigDecimal distance = param.getDistance();
        //超出起步价的额外总价格
        //distance是否超过了baseMileage 超过是大于0 
        if(distance.compareTo(baseMileage)>0){
            BigDecimal exceed = distance.subtract(baseMileage);
            callDriverCalculatedBillResult.setMileageAmount(exceed.multiply(exceedEveryKmAmount));
        }
        //免费等待乘客分钟数
        Integer freeBaseWaitingMinute = ruleWait.getFreeBaseWaitingMinute();
        callDriverCalculatedBillResult.setFreeBaseWaitingMinute(freeBaseWaitingMinute);
        //超出免费等待时长每分钟单价
        Integer waitTime = param.getWaitTime();
        if (ObjectUtil.isNotNull(waitTime)&& waitTime.compareTo(freeBaseWaitingMinute)>0){
            callDriverCalculatedBillResult.setWaitingAmount(ruleWait.getExceedEveryMinuteAmount().multiply(BigDecimal.valueOf(waitTime)));

        }
        //返程免费公里数
        BigDecimal freeBaseReturnMileage = ruleReturn.getFreeBaseReturnMileage();
        callDriverCalculatedBillResult.setFreeBaseReturnMileage(freeBaseReturnMileage);
        //返程超出免费公里每公里单价
        BigDecimal returnExceedEveryKmAmount = ruleReturn.getExceedEveryKmAmount();
        callDriverCalculatedBillResult.setExceedBaseReturnEveryKmAmount(returnExceedEveryKmAmount);
        //返程超出免费公里数额外总价
        if(distance.compareTo(freeBaseReturnMileage)>0){
            //.subtract相当于减法
            BigDecimal overMile = distance.subtract(freeBaseReturnMileage);
            callDriverCalculatedBillResult.setReturnAmont(overMile.multiply(returnExceedEveryKmAmount));
        }
        //预估订单总价格
        callDriverCalculatedBillResult.setExpectsOrderAmount(callDriverCalculatedBillResult.getBaseMileageAmount()
                .add(callDriverCalculatedBillResult.getMileageAmount())
                .add(callDriverCalculatedBillResult.getWaitingAmount())
                .add(callDriverCalculatedBillResult.getReturnAmont())
        );

        return R.success(callDriverCalculatedBillResult);
    }

    /**
     * 计算平台司机分账比例
     * @param sharedAmountDto
     * @return
     */
    @Override
    public R<SharedAmountResult> sharedAmount(SharedAmountDto sharedAmountDto) {
        //1.参数校验
        //2.业务校验
        //2.1.判断基础规则是否存在
        ProfitsharingRuleBase ruleBase = profitsharingRuleBaseService.getOne(new LambdaQueryWrapper<ProfitsharingRuleBase>().eq(ProfitsharingRuleBase::getStatus, 0));
        AssertUtil.isNotNull(ruleBase,"规则未开启或不存在！");
        //获得司机分成比例
        BigDecimal driverRatio = ruleBase.getDriverRatio();
        Integer todayCancel = sharedAmountDto.getTodayCancel();
        Integer todayComplaint = sharedAmountDto.getTodayComplaint();
        BigDecimal totalAmount = sharedAmountDto.getTotalAmount();

        //判断取消数是否大于0，大于0则扣减比例
        if (todayCancel >0) {
            ProfitsharingRuleDeduct ruleDeduct = profitsharingRuleDeductService.getOne(new LambdaQueryWrapper<ProfitsharingRuleDeduct>()
                    .eq(ProfitsharingRuleDeduct::getType, 0)
                    .le(ProfitsharingRuleDeduct::getNumberFrom, todayCancel)
                    .ge(ProfitsharingRuleDeduct::getNumberTo, todayCancel)
            );
            AssertUtil.isNotNull(ruleDeduct, GlobalExceptionCode.SERVICE_ERROR);
            BigDecimal driverRatioDeduct = ruleDeduct.getDriverRatioDeduct();
             driverRatio = driverRatio.subtract(driverRatioDeduct);
        }
        //3.2 判断投诉数是否大于0，大于0扣减比例
        if (todayComplaint > 0) {
            ProfitsharingRuleDeduct ruleDeduct = profitsharingRuleDeductService.getOne(new LambdaQueryWrapper<ProfitsharingRuleDeduct>()
                    .eq(ProfitsharingRuleDeduct::getType, 1)
                    .le(ProfitsharingRuleDeduct::getNumberFrom, todayComplaint)
                    .ge(ProfitsharingRuleDeduct::getNumberTo, todayComplaint)
            );
            AssertUtil.isNotNull(ruleDeduct, GlobalExceptionCode.SERVICE_ERROR);
            BigDecimal driverRatioDeduct = ruleDeduct.getDriverRatioDeduct();
            driverRatio = driverRatio.subtract(driverRatioDeduct);
        }
        SharedAmountResult sharedAmountResult = new SharedAmountResult();

        //用1 -司机比例 =平台比例
        sharedAmountResult.setPlatformRate(BigDecimal.ONE.subtract(driverRatio));
        //司机比例
        sharedAmountResult.setDriverRate(driverRatio);
        //总金额 x 司机比例 = 司机金额
        sharedAmountResult.setDriverIncome(totalAmount.multiply(driverRatio));
        //总金额 - 司机金额 =平台金额
        sharedAmountResult.setPlatformIncome(totalAmount.subtract(sharedAmountResult.getDriverIncome()));

        return R.success(sharedAmountResult);
    }
}
